package com.xiaoyu.lanling.media.selector.matisse

import `in`.srain.cube.cache.DiskFileUtils
import `in`.srain.cube.util.CLog
import android.Manifest
import android.annotation.SuppressLint
import android.app.Activity
import android.content.Intent
import android.content.pm.ActivityInfo
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.os.Environment
import android.text.TextUtils
import com.tbruyelle.rxpermissions2.RxPermissions
import com.xiaoyu.base.app.AppContext
import com.xiaoyu.base.app.GlobalUI
import com.xiaoyu.base.utils.ListUtil
import com.xiaoyu.lanling.BuildConfig
import com.xiaoyu.lanling.R
import com.xiaoyu.lanling.activity.base.AppCompatToolbarActivity
import com.xiaoyu.lanling.event.media.mediaselector.MediaSelectorResultEvent
import com.xiaoyu.lanling.media.selector.MediaSelector
import com.xiaoyu.lanling.media.selector.MediaSelector.Companion.instance
import com.xiaoyu.lanling.media.selector.MediaSelectorType.ALL
import com.xiaoyu.lanling.media.selector.MediaSelectorType.IMAGE
import com.xiaoyu.lanling.media.selector.MediaSelectorType.IMAGE_WITH_GIF
import com.xiaoyu.lanling.media.selector.MediaSelectorType.MediaSelectorTypeDef
import com.xiaoyu.lanling.media.selector.MediaSelectorType.TINY_VIDEO
import com.xiaoyu.lanling.media.selector.MediaSelectorType.TINY_VIDEO_ONLY
import com.xiaoyu.lanling.media.selector.MediaSelectorType.VIDEO
import com.xiaoyu.media.matisse.Matisse.Companion.from
import com.xiaoyu.media.matisse.Matisse.Companion.obtainOriginalChecked
import com.xiaoyu.media.matisse.Matisse.Companion.obtainResult
import com.xiaoyu.media.matisse.MimeType
import com.xiaoyu.media.matisse.MimeType.Companion.of
import com.xiaoyu.media.matisse.MimeType.Companion.ofAll
import com.xiaoyu.media.matisse.MimeType.Companion.ofImage
import com.xiaoyu.media.matisse.MimeType.Companion.ofVideo
import com.xiaoyu.media.matisse.engine.impl.PicassoEngine
import com.xiaoyu.media.matisse.internal.entity.CaptureStrategy
import com.xiaoyu.media.matisse.internal.entity.SelectionResult.Companion.createFromCapture
import com.xiaoyu.media.matisse.internal.utils.PathUtils.getPath
import com.yalantis.ucrop.UCrop
import java.io.File
import java.util.*

class MediaMatisseActivity : AppCompatToolbarActivity() {

    @SuppressLint("CheckResult")
    override fun onCreateSafelyAfterAppFinishInit(savedInstanceState: Bundle?) {
        val requestPermissions = LinkedList<String>()
        requestPermissions.add(Manifest.permission.WRITE_EXTERNAL_STORAGE)
        requestPermissions.add(Manifest.permission.READ_EXTERNAL_STORAGE)

        if (instance.withCamera) {
            requestPermissions.add(Manifest.permission.CAMERA)
        }
        if (isFinishing || isDestroyed) {
            return
        }

        RxPermissions(this).request(*requestPermissions.toTypedArray())
                .subscribe({ granted: Boolean ->
                    if (granted) {
                        if (checkVIVOReadExternalStoragePermission()) {
                            matisse()
                        }
                    } else {
                        GlobalUI.getInstance().showToast("请检查权限是否开启哦")
                        finish()
                    }
                }) { obj: Throwable -> obj.printStackTrace() }
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (resultCode != Activity.RESULT_OK) {
            resetAndFinish()
            return
        }
        processRequest(requestCode, data)
    }

    private fun processRequest(requestCode: Int, data: Intent?) {
        when (requestCode) {
            MediaSelector.REQUEST_CODE_CHOOSE -> {
                if (choose(data)) {
                    resetAndFinish()
                }
            }
            UCrop.REQUEST_CROP -> {
                crop(data)
                resetAndFinish()
            }
        }
    }

    private fun crop(data: Intent?) {
        val uri = UCrop.getOutput(data!!) ?: return
        val path = getPath(this, uri)
        val mediaSelector = instance
        MediaSelectorResultEvent(mediaSelector.mediaType, mediaSelector.fromType, createFromCapture(path), false).post()
    }

    private fun choose(data: Intent?): Boolean {
        val mediaSelector = instance
        val result = obtainResult(data!!)
        val originalChecked = obtainOriginalChecked(data)
        return if (mediaSelector.isWithCrop && result != null && result.isNotEmpty()) {
            if (ListUtil.isHasIndex(result.mediaList, 0)) {
                startCrop(result.mediaList[0].path)
            }
            false
        } else {
            MediaSelectorResultEvent(mediaSelector.mediaType, mediaSelector.fromType, result, originalChecked).post()
            true
        }
    }

    private fun resetAndFinish() {
        instance.reset()
        finish()
    }

    override fun isSetRequestedOrientationPortrait(): Boolean {
        return Build.VERSION.SDK_INT != Build.VERSION_CODES.O
    }

    private fun matisse() {
        val mediaSelector = instance

        @MediaSelectorTypeDef
        val mediaType = mediaSelector.mediaType
        val maxCount = mediaSelector.maxCount
        val withCamera = mediaSelector.withCamera
        val original = mediaSelector.original
        val authority = BuildConfig.APPLICATION_ID + ".file.provider"
        CLog.i(TAG, "matisse mediaType: %s, maxCount: %s, withCamera: %s", mediaType, maxCount, withCamera)
        if (maxCount < 1) {
            CLog.e(TAG, "maxCount < 1: %s", maxCount)
        }
        when (mediaType) {
            IMAGE -> from(this)
                    .choose(of(MimeType.JPEG, MimeType.PNG, MimeType.WEBP, MimeType.BMP), true)
                    .showSingleMediaType(true)
                    .theme(R.style.Matisse)
                    .spanCount(3)
                    .capture(withCamera)
                    .captureStrategy(CaptureStrategy(true, authority))
                    .originalEnable(original)
                    .countable(false)
                    .maxSelectable(Math.max(maxCount, 1))
                    .restrictOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT)
                    .thumbnailScale(0.85f)
                    .imageEngine(PicassoEngine())
                    .forResult(MediaSelector.REQUEST_CODE_CHOOSE)
            IMAGE_WITH_GIF -> from(this)
                    .choose(ofImage(), true)
                    .showSingleMediaType(true)
                    .theme(R.style.Matisse)
                    .spanCount(3)
                    .capture(withCamera)
                    .originalEnable(original)
                    .captureStrategy(CaptureStrategy(true, authority))
                    .countable(false)
                    .maxSelectable(Math.max(maxCount, 1))
                    .restrictOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT)
                    .thumbnailScale(0.85f)
                    .imageEngine(PicassoEngine())
                    .forResult(MediaSelector.REQUEST_CODE_CHOOSE)
            VIDEO -> from(this)
                    .choose(ofVideo(), true)
                    .showSingleMediaType(true)
                    .theme(R.style.Matisse)
                    .spanCount(3)
                    .capture(false)
                    .captureStrategy(CaptureStrategy(true, authority))
                    .countable(false)
                    .maxSelectable(Math.max(maxCount, 1))
                    .restrictOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT)
                    .thumbnailScale(0.85f)
                    .imageEngine(PicassoEngine())
                    .forResult(MediaSelector.REQUEST_CODE_CHOOSE)
            ALL -> from(this)
                    .choose(ofAll(), true)
                    .showSingleMediaType(true)
                    .theme(R.style.Matisse)
                    .spanCount(3)
                    .capture(false)
                    .captureStrategy(CaptureStrategy(true, authority))
                    .countable(false)
                    .maxSelectable(Math.max(maxCount, 1))
                    .restrictOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT)
                    .thumbnailScale(0.85f)
                    .imageEngine(PicassoEngine())
                    .forResult(MediaSelector.REQUEST_CODE_CHOOSE)
            TINY_VIDEO -> from(this)
                    .choose(ofAll(), true)
                    .addFilter(VideoDurationFilter(ofAll(), instance.maxVideoDuration, instance.videoIncapableMessage))
                    .showSingleMediaType(true)
                    .theme(R.style.Matisse)
                    .spanCount(3)
                    .capture(false)
                    .captureStrategy(CaptureStrategy(true, authority))
                    .countable(false)
                    .maxSelectable(Math.max(maxCount, 1))
                    .restrictOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT)
                    .thumbnailScale(0.85f)
                    .imageEngine(PicassoEngine())
                    .forResult(MediaSelector.REQUEST_CODE_CHOOSE)
            TINY_VIDEO_ONLY ->
                from(this)
                        .choose(ofVideo(), true)
                        .addFilter(VideoDurationFilter(ofVideo(), instance.maxVideoDuration, instance.videoIncapableMessage))
                        .showSingleMediaType(true)
                        .theme(R.style.Matisse)
                        .spanCount(3)
                        .capture(false)
                        .captureStrategy(CaptureStrategy(true, authority))
                        .countable(false)
                        .maxSelectable(Math.max(maxCount, 1))
                        .restrictOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT)
                        .thumbnailScale(0.85f)
                        .imageEngine(PicassoEngine())
                        .forResult(MediaSelector.REQUEST_CODE_CHOOSE)
        }
    }

    private fun startCrop(path: String?) {
        if (TextUtils.isEmpty(path)) {
            return
        }
        val file = File(path)
        if (!file.exists()) {
            return
        }
        val options = UCrop.Options()
        options.setStatusBarColor(AppContext.getColor(R.color.cpColorPrimaryDark))
        options.setToolbarColor(AppContext.getColor(R.color.cpColorPrimary))
        options.setToolbarWidgetColor(AppContext.getColor(R.color.cpColorPrimaryText))
        options.setActiveWidgetColor(AppContext.getColor(R.color.cpColorAccent))
        val outFile = File(DiskFileUtils.wantFilesPath(AppContext.getContext(), true)
                + "/Crop/" + "cp_" + System.currentTimeMillis() + ".jpg")
        if (!outFile.parentFile.exists()) {
            outFile.parentFile.mkdirs()
        }
        val mediaSelector = instance
        UCrop.of(Uri.fromFile(file), Uri.fromFile(outFile))
                .withAspectRatio(mediaSelector.withCropAspectRatioX.toFloat(), mediaSelector.withCropAspectRatioY.toFloat())
                .withOptions(options)
                .start(this)
    }

    // waiting update
    private fun checkVIVOReadExternalStoragePermission(): Boolean {
        val manufacturer = Build.MANUFACTURER + ""
        return if (manufacturer.equals("vivo", ignoreCase = true)) {
            try {
                checkReadStorage()
            } catch (e: Exception) {
                GlobalUI.getInstance().showToast("请检查存储权限是否开启哦")
                false
            }
        } else true
    }

    private fun checkReadStorage(): Boolean {
        val file = File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).path)
        val files = file.listFiles()
        val sdPath = Environment.getExternalStorageDirectory().absolutePath
        return files != null || !TextUtils.isEmpty(sdPath)
    }

    companion object {
        private val TAG = MediaMatisseActivity::class.java.simpleName
    }
}